package com.ruoyi.system.utils;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.domain.vo.TransferBillsVo;
import com.ruoyi.system.domain.vo.TransferSceneReportInfo;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.http.*;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;


public class V3PayUtil {

    private static final Logger logger = LoggerFactory.getLogger(V3PayUtil.class);


    public static String merchantId = "1674148676";
    public static String mpAappid = "wx86ad7950e07218a5";
    public static String h5Aappid = "wx8c726aef4a4b511a";


    /** 商户API私钥路径 */
    public static String ApiPrivateKeyPath = "/home/project/bjx_project/1674148676_20250424_cert/apiclient_key.pem";
    /**商户Api证书序列号*/
    public static String ApiSerialNumber = "51B8619641B0C84C3F644D0BDEBB236622EAF580";
    /** 商户APIV3密钥 */
    public static String apiV3Key = "MJMHGTLGIRKEUR2WNN5FOZTLMZGVKV2I";
    /** 转账路劲 */
    public static String transferBillsUrl =  "https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills";
    /** 商户平台密钥路径 */
    public static String  plemPrivateKeyPath =" /home/project/bjx_project/1674148676_20250424_cert/apiclient_key.pem";

    /** 商户平台证书序列号 */
    public static String plemSerialNumber = "6EB07F2E3CB754ACAEE7598355334816E2203781";

    public static String transfer_scene_id="1000";

    public static String user_recv_perception="现金奖励";
    public static String  notify_url="https://www.baijixing.com.cn/api/paynotify/batchTransferNotice";

    public static String  selectTransferUrl="https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/{transfer_bill_no}" ;




    /**
     * 发起转账
     *

     */
    public static TransferBillsVo createTransferBills(TransferBillsVo transferBillsVo) {
        if(transferBillsVo.getPaymentChannels().equals(TokenUtil.platforms_MP)){
            transferBillsVo.setAppId(mpAappid);
        }else if (transferBillsVo.getPaymentChannels().equals(TokenUtil.platforms_H5) ){
            transferBillsVo.setAppId(h5Aappid);
        }

        transferBillsVo.setMchId(merchantId);
        OkHttpClient okHttpClient = new OkHttpClient();
        HttpClient httpClient = new DefaultHttpClientBuilder()
                .config(rsaAutoCertificateConfig())
                .okHttpClient(okHttpClient)
                .build();
        HttpHeaders headers = new HttpHeaders();
        headers.addHeader("Accept", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Wechatpay-Serial", ApiSerialNumber);

        HashMap<Object, Object> map = new HashMap<>();
        // 商户AppID
        map.put("appid", transferBillsVo.getAppId());
        // 商户单号
        map.put("out_bill_no", transferBillsVo.getOutBillNo());
        // 转账场景ID
        map.put("transfer_scene_id", transfer_scene_id);
        // 收款用户OpenID
        map.put("openid", transferBillsVo.getOpenid());
        // 转账金额（单位：分）
        map.put("transfer_amount", transferBillsVo.getTransferAmount());
        // 转账备注
        map.put("transfer_remark", transferBillsVo.getTransferRemark());
        // 回调通知地址
        map.put("notify_url", notify_url);
        // 用户收款感知
        map.put("user_recv_perception", user_recv_perception);
       // 转账场景报备信息
        JSONArray jsonArray = new JSONArray();


        List<TransferSceneReportInfo> transferSceneReportInfos = transferBillsVo.getTransferSceneReportInfos();
        transferSceneReportInfos.stream().forEach(a ->{
            jsonArray.add(new JSONObject().fluentPut("info_type", a.getInfoType()).fluentPut("info_content",a.getInfoContent()));

        });
        map.put("transfer_scene_report_infos", jsonArray);
        logger.info("打款发起参数："+JSONUtil.toJsonStr(map));
        JsonRequestBody build = new JsonRequestBody.Builder()
                .body(JSONUtil.toJsonStr(map))
                .build();
        HttpRequest executeSendGetHttpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .url(transferBillsUrl)
                .headers(headers)
                .body(build)
                .build();

            HttpResponse<JSONObject> execute = httpClient.execute(executeSendGetHttpRequest, JSONObject.class);
            JSONObject responseBody = execute.getServiceResponse();
            logger.info("发起转账返回：{}", responseBody.toJSONString());
            transferBillsVo.setReturnJSONObject(responseBody);
            return transferBillsVo;

    }

    /**
     * API安全加密配置
     */
    private static  RSAAutoCertificateConfig rsaAutoCertificateConfig() {
        return new RSAAutoCertificateConfig.Builder()
                // 商户号
                .merchantId(merchantId)
                // 商户API证书私钥的存放路径
                .privateKeyFromPath(ApiPrivateKeyPath)
                // 商户API证书序列号
                .merchantSerialNumber(ApiSerialNumber)
                // APIv3密钥
                .apiV3Key(apiV3Key)
                .build();
    }

    /**
     * 敏感信息加密
     */
    private static String rsaEncryptOAEP(String message) {
        X509Certificate cert = getX509Certificate();
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, cert.getPublicKey());
            byte[] data = message.getBytes(StandardCharsets.UTF_8);
            byte[] cipherdata = cipher.doFinal(data);
            return Base64.getEncoder().encodeToString(cipherdata);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取 X509Certificate
     */
    private static X509Certificate getX509Certificate() {
        try {
            InputStream inputStream = (InputStream)new FileInputStream(plemPrivateKeyPath);
            if (inputStream == null) {
                throw new IOException("Resource not found: v3/platform_cert.pem");
            }
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            return (X509Certificate) cf.generateCertificate(inputStream);

        } catch (IOException | CertificateException e) {
            throw new RuntimeException(e);
        }


    }


    public  static  void selectTransfer(String transferBillNo){
        String replaceUrl = selectTransferUrl.replace("{transfer_bill_no}", transferBillNo);
        OkHttpClient okHttpClient = new OkHttpClient();
        HttpClient httpClient = new DefaultHttpClientBuilder()
                .config(rsaAutoCertificateConfig())
                .okHttpClient(okHttpClient)
                .build();
        HttpHeaders headers = new HttpHeaders();
        headers.addHeader("Accept", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Content-Type", MediaType.APPLICATION_JSON.getValue());
        headers.addHeader("Wechatpay-Serial", ApiSerialNumber);

        HttpRequest executeSendGetHttpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.GET)
                .url(replaceUrl)
                .headers(headers)
                .build();

        HttpResponse<JSONObject> execute = httpClient.execute(executeSendGetHttpRequest, JSONObject.class);
        JSONObject responseBody = execute.getServiceResponse();
        logger.info("发起查询转账返回：{}", responseBody.toJSONString());

    }



}
